package com.example.springbootshirp.matcher;

import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.springframework.stereotype.Component;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author 墨苍璃
 */
@Component
public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {

    /**
     * 声明缓存对象
     */
    private Ehcache passwordRetryEhcache;


    /**
     * 声明构造方法获取缓存对象
     *
     * @param ehCacheManager
     */
    public RetryLimitHashedCredentialsMatcher(EhCacheManager ehCacheManager) {
        passwordRetryEhcache = ehCacheManager.getCacheManager().getCache("passwordRetryEhcache");
    }


    /**
     * 复写父类的登录认证方法，该方法由shiro的login方法在底层调用
     *
     * @param token
     * @param info
     * @return
     */
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        //声明变量记录错误次数
        int i = 0;
        //1.获取用户的登录次数的缓存信息
        //获取用户的身份信息(身份信息为缓存数据的键名)
        String username = token.getPrincipal().toString();
        System.out.println(username);
        System.out.println("_____________________________________");
        //获取缓存对象
        Element element = passwordRetryEhcache.get(username);
        //2.判断是否有缓存数据
        if (element == null) {//没有缓存登录的错误次数，则创建新的缓存
            Element ele = new Element(username, new AtomicInteger(0));
            passwordRetryEhcache.put(ele);
        } else {
            //有缓存直接递增
            AtomicInteger atomicInteger = (AtomicInteger) element.getObjectValue();
            i = atomicInteger.incrementAndGet();
        }
        //3.判断i的值是否4次
        if (i >= 4) {
            throw new ExcessiveAttemptsException();
        }
        //4.进行本次请求的登录
        boolean match = super.doCredentialsMatch(token, info);
        //5. 如果登录成功则将错误次数的缓存删除
        if (match) {
            passwordRetryEhcache.remove(username);
        }

        return match;
    }

}
